package org.finesys.common.redis.config;

import java.util.List;

import org.finesys.common.redis.core.event.consume.KeyDeletedEventMessageConsume;
import org.finesys.common.redis.core.event.consume.KeyExpiredEventMessageConsume;
import org.finesys.common.redis.core.event.consume.KeySetEventMessageConsume;
import org.finesys.common.redis.core.event.listener.AbstractKeyDeletedEventMessageListener;
import org.finesys.common.redis.core.event.listener.AbstractKeyExpiredEventMessageListener;
import org.finesys.common.redis.core.event.listener.AbstractKeySetEventMessageListener;
import org.finesys.common.redis.core.event.listener.impl.DefaultKeyDeletedEventMessageListener;
import org.finesys.common.redis.core.event.listener.impl.DefaultKeyExpiredEventMessageListener;
import org.finesys.common.redis.core.event.listener.impl.DefaultKeySetEventMessageListener;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;

@AutoConfiguration
public class RedisKeyEventAutoConfiguration {

	@ConditionalOnProperty(prefix = "redis.key.del", name = "enabled", havingValue = "true")
	@Configuration
	public static class RedisKeyDeletedEventConfiguration {

		@Bean(name = "keyDeleteEventRedisMessageListenerContainer")
		@ConditionalOnMissingBean(name = "keyDeleteEventRedisMessageListenerContainer")
		public RedisMessageListenerContainer redisMessageListenerContainer(
				RedisConnectionFactory redisConnectionFactory) {
			RedisMessageListenerContainer container = new RedisMessageListenerContainer();
			container.setConnectionFactory(redisConnectionFactory);
			return container;
		}

		@Bean(name = "keyDeletedEventMessageListener")
		@ConditionalOnMissingBean(name = "keyDeletedEventMessageListener")
		public AbstractKeyDeletedEventMessageListener keyDeletedEventMessageListener(@Qualifier(
				value = "keyDeleteEventRedisMessageListenerContainer") RedisMessageListenerContainer redisMessageListenerContainer,
				ObjectProvider<List<KeyDeletedEventMessageConsume>> KeyDeletedEventMessageConsumes) {
			return new DefaultKeyDeletedEventMessageListener(redisMessageListenerContainer,
					KeyDeletedEventMessageConsumes);
		}

	}

	@ConditionalOnProperty(prefix = "redis.key.set", name = "enabled", havingValue = "true")
	@Configuration
	public static class RedisKeySetEventConfiguration {

		@Bean(name = "keySetEventRedisMessageListenerContainer")
		@ConditionalOnMissingBean(name = "keySetEventRedisMessageListenerContainer")
		public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
			RedisMessageListenerContainer container = new RedisMessageListenerContainer();
			container.setConnectionFactory(connectionFactory);
			return container;
		}

		@Bean(name = "keySetEventMessageListener")
		@ConditionalOnMissingBean(name = "keySetEventMessageListener")
		public AbstractKeySetEventMessageListener keySetEventMessageListener(@Qualifier(
				value = "keySetEventRedisMessageListenerContainer") RedisMessageListenerContainer listenerContainer,
				ObjectProvider<List<KeySetEventMessageConsume>> keySetEventMessageConsumes) {
			return new DefaultKeySetEventMessageListener(listenerContainer, keySetEventMessageConsumes);
		}

	}

	@ConditionalOnProperty(prefix = "redis.key.expired", name = "enabled", havingValue = "true")
	@Configuration
	public static class RedisKeyExpiredEventConfiguration {

		@Bean(name = "keyExpiredEventRedisMessageListenerContainer")
		@ConditionalOnMissingBean(name = "keyExpiredEventRedisMessageListenerContainer")
		public RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory connectionFactory) {
			RedisMessageListenerContainer container = new RedisMessageListenerContainer();
			container.setConnectionFactory(connectionFactory);
			return container;
		}

		@Bean(name = "keyExpiredEventMessageListener")
		@ConditionalOnMissingBean(name = "keyExpiredEventMessageListener")
		public AbstractKeyExpiredEventMessageListener keyExpiredEventMessageListener(@Qualifier(
				value = "keyExpiredEventRedisMessageListenerContainer") RedisMessageListenerContainer listenerContainer,
				ObjectProvider<List<KeyExpiredEventMessageConsume>> keyExpiredEventMessageConsumes) {
			return new DefaultKeyExpiredEventMessageListener(listenerContainer, keyExpiredEventMessageConsumes);
		}

	}

}
